package li.buda.utils.flex.remoting {
    import flash.utils.getQualifiedClassName;

    import mx.controls.Alert;
    import mx.messaging.ChannelSet;
    import mx.messaging.channels.AMFChannel;
    import mx.rpc.AbstractOperation;
    import mx.rpc.events.FaultEvent;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.remoting.RemoteObject;

    public class RemoteObjectInvoker implements RemotingInvoker {
        private static function create():RemoteObject {
            var ro:RemoteObject = new RemoteObject();
            ro.channelSet = channelSet;
            ro.destination = "rubyamf";
            return ro;
        }

        private static var _channelSet:ChannelSet;
        private static function get channelSet():ChannelSet {
            if (_channelSet == null) {
                _channelSet = new ChannelSet();
                var chan:AMFChannel = new AMFChannel("rubyamf", "http://localhost:3000/rubyamf/gateway");
                chan.pollingEnabled = false;
                _channelSet.addChannel(chan);
            }
            return _channelSet;
        }

        private var _ro:RemoteObject = create();

        public function RemoteObjectInvoker(destination:String) {
            //            _ro.destination = destination;
            _ro.source = destination;
        }

        public function invoke(methodName:String, arguments:Object = null, onResult:Function = null, onFault:Function = null):void {
            var op:AbstractOperation = _ro.getOperation(methodName);
            var fOnResult:Function = function(event:ResultEvent):void {
                op.removeEventListener(ResultEvent.RESULT, fOnResult);
                op.removeEventListener(FaultEvent.FAULT, fOnFault);
                trace(getQualifiedClassName(event.result));
                onResult(event.result);
            }
            var fOnFault:Function = function(event:FaultEvent):void {
                op.removeEventListener(ResultEvent.RESULT, fOnResult);
                op.removeEventListener(FaultEvent.FAULT, fOnFault);
                if (onFault != null) {
                    onFault(event.fault);
                } else {
                    defaultOnFault(event.fault);
                }
            }
            op.addEventListener(ResultEvent.RESULT, fOnResult);
            op.addEventListener(FaultEvent.FAULT, fOnFault);
            if (arguments != null) {
                op.arguments = arguments;
            }
            op.send();
        }

        private function defaultOnFault(error:Error):void {
            Alert.show(error.message);
        }

    }
}